cmake_minimum_required(VERSION 3.12.4)
project(STM32_Project C)

# 基本配置 ================================================================
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXECUTABLE_SUFFIX ".elf")

# 交叉编译配置 ============================================================
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)

# 微库配置开关 ===========================================================
option(USE_MICROLIB "Enable MicroLib" ON)

# 源文件配置 ==============================================================
if(USE_MICROLIB)
    set(STARTUP_FILE "startup_stm32f103xe_microlib.s")
    add_compile_definitions(USE_MICROLIB __MICROLIB)
else()
    set(STARTUP_FILE "startup_stm32f103xe.s")
endif()

file(GLOB_RECURSE SOURCES
    "StartUp/${STARTUP_FILE}"
    "System/*.c"
    "Driver/src/*.c"
    "FWLib/src/*.c"
    "BSP/*.c"
    "Middleware/src/*.c"
    "User/*.c"
    "UserTaskThread/*.c"
    "Hardware_stm32f103/*.c"
)

# 头文件包含 ==============================================================
include_directories(
    Config
    DesignData
    Driver/inc
    FWLib/inc
    Middleware/inc
    BSP
    Hardware_stm32f103
    User
    UserTaskThread
    System
    Thirdparty
)

# 编译选项 ================================================================
add_compile_options(
    -mcpu=cortex-m3
    -mthumb
    -ffunction-sections
    -fdata-sections
    -g
    -Os
    -DUSE_STDPERIPH_DRIVER
    -DSTM32F103xE
    $<$<BOOL:${USE_MICROLIB}>:-D__NO_SYSTEM_INIT>
    -Wall
    -Wno-unused-parameter
)

# 链接选项 ================================================================
set(LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/mdk/STM32F103XE_FLASH.ld")

add_link_options(
    -mcpu=cortex-m3
    -mthumb
    --specs=nano.specs
    $<$<BOOL:${USE_MICROLIB}>:--specs=microlib.specs>
    -Wl,--gc-sections
    -Wl,--print-memory-usage
    -Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map
    -T "${LINKER_SCRIPT}"
    -u _printf_float
    -u _scanf_float
    -Wl,--entry=Reset_Handler
)

# 生成目标 ================================================================
add_executable(${PROJECT_NAME} ${SOURCES})

# 后处理命令 ==============================================================
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${PROJECT_NAME}> ${PROJECT_NAME}.hex
    COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${PROJECT_NAME}> ${PROJECT_NAME}.bin
    COMMENT "Generating HEX and BIN files"
)

# 烧录目标 ================================================================
add_custom_target(flash
    DEPENDS ${PROJECT_NAME}
    COMMAND st-flash --reset write ${PROJECT_NAME}.bin 0x8000000
    COMMENT "Flashing device..."
)

# 调试配置 ================================================================
set(DEBUG_SCRIPT "${CMAKE_SOURCE_DIR}/mdk/DebugConfig/gdbinit.cfg")
if(EXISTS ${DEBUG_SCRIPT})
    add_custom_target(debug
        COMMAND arm-none-eabi-gdb -x ${DEBUG_SCRIPT} ${PROJECT_NAME}.elf
        DEPENDS ${PROJECT_NAME}
    )
endif()